﻿using System;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using NerdWare.Crm2011VsTools.DialogPages;
using NerdWare.Crm2011VsTools.Globals;
using NerdWare.Crm2011VsTools.ToolWindows;
using NerdWare.Crm2011VsTools.ViewModel;

namespace NerdWare.Crm2011VsTools.Controls
{
    /// <summary>
    /// Interaction logic for ScriptInjectorControl.xaml
    /// </summary>
    public partial class ScriptInjectorControl : IDisposable
    {
        private readonly ScriptInjectorToolWindow _scriptInjectorToolWindow;

        private readonly OleMenuCommand _onOffMenu;
        private readonly OleMenuCommand _connectionMenu;
        private readonly OleMenuCommand _connectionListMenu;
        //private Window _outputWindow;

        //public OleMenuCommand AddMenuCommand(OleMenuCommandService msc, Guid commandId, int id, EventHandler handler)
        //{
        //    CommandID cmd = new CommandID(commandId, id);
        //    OleMenuCommand oleMenu = new OleMenuCommand(handler, cmd);
        //    msc.AddCommand(oleMenu);

        //    return oleMenu;
        //}

        public ScriptInjectorControl(ScriptInjectorToolWindow scriptInjectorToolWindow)
        {
            _scriptInjectorToolWindow = scriptInjectorToolWindow;
            DataContext = new ScriptInjectorViewModel();

            //DTE dte = (DTE)_scriptInjectorToolWindow.GetService(typeof(DTE));
            //if (dte != null)
            //{
            //    _outputWindow = dte.Windows.Item(Constants.vsWindowKindOutput);
            //}

            OleMenuCommandService mcs = _scriptInjectorToolWindow.Mcs;
            if (null != mcs)
            {
                // Start Stop-Button
                CommandID onOffCmd = new CommandID(GuidList.Crm2011VsToolsCmdSet, PkgCmdIDList.CmdIdScriptInjectorStart);
                _onOffMenu = new OleMenuCommand(StartStopp, onOffCmd);
                mcs.AddCommand(_onOffMenu);

                // Command for the combo itself
                CommandID connectionCmd = new CommandID(GuidList.Crm2011VsToolsCmdSet, PkgCmdIDList.CmdIdScriptInjectorConnection);
                _connectionMenu = new OleMenuCommand(ComboHandler, connectionCmd);
                mcs.AddCommand(_connectionMenu);

                // Command for the combo's list
                CommandID connectionListCmd = new CommandID(GuidList.Crm2011VsToolsCmdSet, PkgCmdIDList.CmdIdScriptInjectorConnectionList);
                _connectionListMenu = new OleMenuCommand(ComboListHandler, connectionListCmd);
                mcs.AddCommand(_connectionListMenu);

                UpdateUi();
            }

            InitializeComponent();
        }

        private void UpdateUi()
        {
            ScriptInjectorViewModel scriptInjectorViewModel = DataContext as ScriptInjectorViewModel;
            if (scriptInjectorViewModel != null)
            {
                if (scriptInjectorViewModel.IsRunning)
                {
                    _onOffMenu.Text = "Stop";
                    _onOffMenu.Checked = true;
                    _connectionListMenu.Enabled = false;
                    _connectionMenu.Enabled = false;
                }
                else
                {
                    _onOffMenu.Text = "Start";
                    _onOffMenu.Checked = false;
                    _onOffMenu.Enabled = _crmServerConnection != null;
                    _connectionListMenu.Enabled = true;
                    _connectionMenu.Enabled = true;
                }
            }
        }

        private void StartStopp(object sender, EventArgs e)
        {
            ScriptInjectorViewModel scriptInjectorViewModel = (ScriptInjectorViewModel)DataContext;
            scriptInjectorViewModel.FlipOnOff(_crmServerConnection);
            UpdateUi();
        }


        private void ComboListHandler(object sender, EventArgs e)
        {
            var eventArgs = e as OleMenuCmdEventArgs;
            if (eventArgs != null)
            {
                IntPtr output = eventArgs.OutValue;
                if (output != null)
                {
                    // Iterate through the array
                    int count = Options.GeneralSetting.CRMServerConnections.Length;
                    if (count > 0)
                    {
                        string[] names = new string[count];

                        for (int i = 0; i <= count - 1; i++)
                        {
                            names[i] = Options.GeneralSetting.CRMServerConnections[i].DisplayName;
                        }
                        Marshal.GetNativeVariantForObject(
                            names, output);
                    }
                }
            }
        }

        private string _crmServerConnectionValue;
        private CrmServerConnection _crmServerConnection;

        private void ComboHandler(object sender, EventArgs e)
        {
            var eventArgs = e as OleMenuCmdEventArgs;
            if (eventArgs != null)
            {
                var output = eventArgs.OutValue;
                var input = eventArgs.InValue;
                if (input != null)
                {
                    // Save away the value from the combobox.
                    _crmServerConnectionValue = input.ToString();
                    _crmServerConnection = null;

                    // Iterate through the array.
                    int count = Options.GeneralSetting.CRMServerConnections.Length;
                    if (count > 0)
                    {
                        for (int i = 0; i <= count - 1; i++)
                        {
                            if (Options.GeneralSetting.CRMServerConnections[i].DisplayName != _crmServerConnectionValue) continue;

                            _crmServerConnection = Options.GeneralSetting.CRMServerConnections[i];
                            Logger.Output.Log("Changed CRM Connection to '{0}'.", _crmServerConnectionValue);

                            UpdateUi();
                            break;
                        }
                    }
                }
                else if (output != null)
                {
                    Marshal.GetNativeVariantForObject(
                        _crmServerConnectionValue, output);
                }
            }
        }

        //public Window OutputWindow
        //{
        //    get
        //    {
        //        if (_outputWindow == null)
        //        {
        //            DTE dte = (DTE) _scriptInjectorToolWindow.GetService(typeof (DTE));
        //            if (dte != null)
        //            {
        //                _outputWindow = dte.Windows.Item(Constants.vsWindowKindOutput);
        //            }
        //        }

        //        return _outputWindow;
        //    }
        //}

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (DataContext != null)
                ((ScriptInjectorViewModel)DataContext).Dispose();
        }

        #endregion
    }
}